﻿using DotsGame;

using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;


partial struct system1_game : ISystem
{
    ThreadRandom trandom;

    EntityQuery queryMainTarget;
    void OnCreate(ref SystemState state)
    {
        //本系统的启动条件
        state.RequireForUpdate<dotscomp_StartTag>();


        trandom = new ThreadRandom();
        trandom.Init();

        queryMainTarget = state.GetEntityQuery(typeof(comp_BattleUnit), typeof(LocalTransform), typeof(comp_BattleUnitTag));
    }
    void OnUpdate(ref SystemState state)
    {
        const float maxdelta = 1.0f / 16.0f;
        var delta = SystemAPI.Time.DeltaTime;
        if (delta > maxdelta)
            delta = maxdelta;

        var data = CommonData.Instance;

        //处理消息，限制一帧处理数量
        var count = data.Data.queueCmdToSystem.Length;
        if (count > 100)
            count = 100;
        for (var i = 0; i < count; i++)
        {
            if (data.Data.queueCmdToSystem.TryDequeue(out var cmd))
            {
                ParseEvent(ref state, ref cmd);
            }
        }

        var ecbsystem = SystemAPI.GetSingleton<EndSimulationEntityCommandBufferSystem.Singleton>();
        

        {//安排Jobs
            var ecb = ecbsystem.CreateCommandBuffer(state.WorldUnmanaged);
            var jobs = new jobs_battleunit()
            {
                trandom = trandom,
                campA = data.Data.campA,
                campB = data.Data.campB,
                delta = delta,
                commandBuffer = ecb.AsParallelWriter(),
                config_effect = data.Data.config_effect,
            };
            state.Dependency = jobs.Schedule(state.Dependency);
        }
        {//安排Jobs
            var ecb = ecbsystem.CreateCommandBuffer(state.WorldUnmanaged);
            var jobs = new jobs_effect()
            {
                trandom = trandom,
           
                delta = delta,
                commandBuffer = ecb.AsParallelWriter(),
              
            };
            state.Dependency = jobs.Schedule(state.Dependency);
        }

        {//安排Jobs
            var jobs = new jobs_rangemove()
            {
                trandom = trandom,
            };
            state.Dependency = jobs.Schedule(state.Dependency);
        }
        state.Dependency.Complete();



        {//update maintarget pos

            queryMainTarget.ResetFilter();

            queryMainTarget.AddSharedComponentFilter(new comp_BattleUnitTag()
            {
                maintarget = true,
                campid = 0,
            });

            var maintargetlist = queryMainTarget.ToComponentDataArray<LocalTransform>(Allocator.Temp);
            for (var i = 0; i < data.Data.campA.mainTargets.Length; i++)
            {
                if (i < maintargetlist.Length)
                {
                    data.Data.campA.mainTargets[i] = new UnitPos
                    {
                        enable = true,
                        pos = maintargetlist[i].Position,
                        half = 35.0f,
                    };
                }
                else
                {
                    data.Data.campA.mainTargets[i] = new UnitPos
                    {
                        enable = false
                    };
                }
            }
        }
    }
    void OnDestroy(ref SystemState state) { }
    void ParseEvent(ref SystemState state, ref CommandToSystem cmd)
    {

        var data = CommonData.Instance;
        if (cmd.type == CommandToSystemType.CreateUnit)
        {
            var es = state.EntityManager.Instantiate(data.Data.config_mesh[cmd.typeid].prefab, cmd.count, Allocator.Temp);
            for (var i = 0; i < es.Length; i++)
            {
                var entity = es[i];
                if (cmd.mode == PosMode.Point)
                {
                    var tran = LocalTransform.FromPositionRotationScale(cmd.pos, quaternion.LookRotation(cmd.dir, new float3(0, 1, 0)), cmd.scale);
                    state.EntityManager.AddComponentData<LocalTransform>(entity, tran);
                }
                else if (cmd.mode == PosMode.BigCircle)
                {
                    var r = math.PI * 2.0f * (float)i / (float)es.Length;
                    var x = math.sin(r) * 200;
                    var z = math.cos(r) * 200;
                    var center = cmd.pos;
                    var pos = new float3(center.x + x + (trandom.NextFloat() - 0.5f) * 5.0f, center.y, center.z + z + (trandom.NextFloat() - 0.5f) * 5.0f);
                    var dir = math.normalize(center - pos);
                    var tran = LocalTransform.FromPositionRotationScale(pos, quaternion.LookRotation(dir, new float3(0, 1, 0)), cmd.scale);
                    state.EntityManager.AddComponentData<LocalTransform>(entity, tran);
                }
                var bunit = new comp_BattleUnit()
                {
                    radius = cmd.maintarget ? 10.0f : 1.0f,
                    campid = cmd.camp,
                    maintarget = cmd.maintarget,
                    speed = 8.0f * (1.0f + (trandom.NextFloat() - 0.5f) * 0.5f)
                };
                state.EntityManager.AddComponentData(entity, bunit);

                var bunittag = new comp_BattleUnitTag()
                {
                    campid = cmd.camp,
                    maintarget = cmd.maintarget,
                };

                state.EntityManager.AddSharedComponent(entity, bunittag);
            }
        }
        if (cmd.type == CommandToSystemType.Create10000)
        {


            var ecs = state.EntityManager.Instantiate(data.Data.config_mesh[0].prefab, 10000, Allocator.Temp);
            foreach (var e in ecs)
            {
                var rpos = new float3(trandom.NextFloat() * 1000, 10, trandom.NextFloat() * 1000);
                var tran = LocalTransform.FromPosition(rpos);
                state.EntityManager.AddComponentData<LocalTransform>(e, tran);
                var move = new dotscomp_rangemove()
                {
                    initpos = rpos,
                    range = 5.0f,
                    newdir = new float3(trandom.NextFloat(), 0, trandom.NextFloat())
                };
                state.EntityManager.AddComponentData<dotscomp_rangemove>(e, move);
            }
        }

    }

}
